﻿using Native.Sdk.Cqp.Core;
using Native.Sdk.Cqp.Enum;
using Native.Sdk.Cqp.Expand;
using System.Runtime.InteropServices;

namespace Native.Sdk.Cqp
{
    /// <summary>
    /// 表示 酷Q日志 的封装类
    /// </summary>
    public class CQLog
    {
        #region --字段--
        private readonly int _authCode = 0;
        #endregion

        #region --属性--
        /// <summary>
        /// 获取当前实例的验证码
        /// </summary>
        public int AuthCode { get { return _authCode; } }
        #endregion

        #region --构造函数--
        /// <summary>
        /// 初始化 <see cref="CQLog"/> 类的新实例, 该实例由 <code>Initialize</code> 函数进行授权
        /// </summary>
        /// <param name="authCode">授权码</param>
        public CQLog(int authCode)
        {
            this._authCode = authCode;
        }
        #endregion

        #region --公开方法--
        /// <summary>
        /// 向酷Q跟踪器发送一条日志, 并且拥有优先级和类型
        /// </summary>
        /// <param name="level">日志的优先级</param>
        /// <param name="type">显示在窗体中的类型</param>
        /// <param name="contents">日志详细信息</param>
        /// <returns>返回当前实例 <see cref="CQLog"/></returns>
        public CQLog WriteLine(CQLogLevel level, string type, params object[] contents)
        {
            GCHandle toSendStringHandle = contents.ToSendString().GetStringGCHandle();
            GCHandle typeHandle = type.GetStringGCHandle();
            try
            {
                CQP.CQ_addLog(this.AuthCode, (int)level, typeHandle.AddrOfPinnedObject(), toSendStringHandle.AddrOfPinnedObject());
                return this;
            }
            finally
            {
                toSendStringHandle.Free();
            }
        }

        /// <summary>
        /// 向酷Q跟踪器发送一条 <see cref="CQLogLevel.Debug"/> 级别的日志, 并拥有自己的类型
        /// </summary>
        /// <param name="type">显示在窗体中的类型</param>
        /// <param name="contents">日志详细信息</param>
        /// <returns>返回当前实例 <see cref="CQLog"/></returns>
        public CQLog Debug(string type, params object[] contents)
        {
            return WriteLine(CQLogLevel.Debug, type, contents);
        }

        /// <summary>
        /// 向酷Q日志跟踪器发送一条 <see cref="CQLogLevel.Info"/> 级别的日志, 并拥有自己的类型
        /// </summary>
        /// <param name="type">显示在窗体中的类型</param>
        /// <param name="contents">日志详细信息</param>
        /// <returns>返回当前实例 <see cref="CQLog"/></returns>
        public CQLog Info(string type, params object[] contents)
        {
            return WriteLine(CQLogLevel.Info, type, contents);
        }

        /// <summary>
        /// 向酷Q日志跟踪器发送一条 <see cref="CQLogLevel.InfoSuccess"/> 级别的日志, 并拥有自己的类型
        /// </summary>
        /// <param name="type">显示在窗体中的类型</param>
        /// <param name="contents">日志详细信息</param>
        /// <returns>返回当前实例 <see cref="CQLog"/></returns>
        public CQLog InfoSuccess(string type, params object[] contents)
        {
            return WriteLine(CQLogLevel.InfoSuccess, type, contents);
        }

        /// <summary>
        /// 向酷Q日志跟踪器发送一条 <see cref="CQLogLevel.InfoReceive"/> 级别的日志, 并拥有自己的类型
        /// </summary>
        /// <param name="type">显示在窗体中的类型</param>
        /// <param name="contents">日志详细信息</param>
        /// <returns>返回当前实例 <see cref="CQLog"/></returns>
        public CQLog InfoReceive(string type, params object[] contents)
        {
            return WriteLine(CQLogLevel.InfoReceive, type, contents);
        }

        /// <summary>
        /// 向酷Q日志跟踪器发送一条 <see cref="CQLogLevel.InfoSend"/> 级别的日志, 并拥有自己的类型
        /// </summary>
        /// <param name="type">显示在窗体中的类型</param>
        /// <param name="contents">日志详细信息</param>
        /// <returns>返回当前实例 <see cref="CQLog"/></returns>
        public CQLog InfoSend(string type, params object[] contents)
        {
            return WriteLine(CQLogLevel.InfoSend, type, contents);
        }

        /// <summary>
        /// 向酷Q日志跟踪器发送一条 <see cref="CQLogLevel.Warning"/> 级别的日志, 并拥有自己的类型
        /// </summary>
        /// <param name="type">显示在窗体中的类型</param>
        /// <param name="contents">日志详细信息</param>
        /// <returns>返回当前实例 <see cref="CQLog"/></returns>
        public CQLog Warning(string type, params object[] contents)
        {
            return WriteLine(CQLogLevel.Warning, type, contents);
        }

        /// <summary>
        /// 向酷Q日志跟踪器发送一条 <see cref="CQLogLevel.Error"/> 级别的日志, 并拥有自己的类型
        /// </summary>
        /// <param name="type">显示在窗体中的类型</param>
        /// <param name="contents">日志详细信息</param>
        /// <returns>返回当前实例 <see cref="CQLog"/></returns>
        public CQLog Error(string type, params object[] contents)
        {
            return WriteLine(CQLogLevel.Error, type, contents);
        }

        /// <summary>
        /// 向酷Q日志跟踪器发送一条 <see cref="CQLogLevel.Fatal"/> 级别的日志, 并拥有自己的类型
        /// </summary>
        /// <param name="type">显示在窗体中的类型</param>
        /// <param name="contents">日志详细信息</param>
        /// <returns>返回当前实例 <see cref="CQLog"/></returns>
        public CQLog Fatal(string type, params object[] contents)
        {
            return WriteLine(CQLogLevel.Error, type, contents);
        }

        /// <summary>
        /// 向酷Q日志跟踪器发送一条 <see cref="CQLogLevel.Fatal"/> 级别的日志, 并弹窗提示错误
        /// </summary>
        /// <param name="contents">日志详细信息</param>
        public void SetFatalMessage(params object[] contents)
        {
            GCHandle handle = contents.ToSendString().GetStringGCHandle();
            try
            {
                CQP.CQ_setFatal(_authCode, handle.AddrOfPinnedObject());
            }
            finally
            {
                handle.Free();
            }
        }
        #endregion
    }
}
